#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   App_WriteDataById_0x2E_test.py
@Time    :   2022/9/13 13:31:28
@Author  :   YangLiang
@Version :   1.0
@Contact :   yangliang@chengtech.com
@License :   (C)Copyright 2022-2025
@Desc    :   None
'''

# here put the import lib
from commDriver.modbus_plc import *
from gettext import find
from xmlrpc.client import Fault
from pytest_assume.plugin import assume

import pytest
import logging
import time
import requests
from sympy import I
# from sympy import assuming
from commDriver.TS_CAN import *
import allure
import sys
from collections.abc import Iterable

from sqlalchemy import false

sys.dont_write_bytecode = True


SID_0x19_reportNumberOfDTCByStatusMask_noFault = [([0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00], [0x19, 0x01, 0x01]),
                                                  ([0x19, 0x01, 0x08], [0x59, 0x01, 0x09, 0x00, 0x00], [0x19, 0x01, 0x08]),
                                                  ([0x19, 0x01, 0x09], [0x59, 0x01, 0x09, 0x00, 0x00], [0x19, 0x01, 0x09]),
                                                  ([0x19, 0x01, 0x0A], [0x59, 0x01, 0x09, 0x00, 0x00], [0x19, 0x01, 0x0A]),
                                                  ([0x19, 0x01, 0x0B], [0x59, 0x01, 0x09, 0x00, 0x00], [0x19, 0x01, 0x0B]),
                                                  ([0x19, 0x01, 0xFF], [0x59, 0x01, 0x09, 0x00, 0x00], [0x19, 0x01, 0xFF])]


class Test_reportNumberOfDTCByStatusMask_phy(object):

   '''NO Fault'''
   ids = ["Request {2}".format(req, resp, binascii.b2a_hex(bytearray(send), ' ')) for req, resp, send in SID_0x19_reportNumberOfDTCByStatusMask_noFault]

   @allure.severity('normal')
   @allure.story('Test read dtc information service 0x19')
   @allure.description('Test reportDTCByStatusMask of 0x19 in default session with physical addressing')
   @allure.testcase('Test cases address:https://chengtech.pingcode.com/testhub/libraries/62a69d6cb35db4f20e37703a/cases')
   @pytest.mark.parametrize('req,resp,title', SID_0x19_reportNumberOfDTCByStatusMask_noFault, ids=ids)
   def test_reportNumberOfDTCByStatusMask_No_Fault_Default_Phy(self, action,  Driver, req, resp, title):
      iStep = 1
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 1, iStep, False, 'UDS', 'ClearFault')
      with allure.step(f'Step{iStep}: Judge fault number of times'):
         with assume: assert uds_resp[5] <= 3 
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19,0x02,0x09], [0x59,0x02,0x09], 0, iStep, False, 'UDS', 'noClearFault')
      iStep = Driver['CAN'].delInitialFailure(iStep,uds_resp)

   @allure.severity('normal')
   @allure.story('Test read dtc information service 0x19')
   @allure.description('Test reportDTCByStatusMask of 0x19 in extended session with physical addressing')
   @allure.testcase('Test cases address:https://chengtech.pingcode.com/testhub/libraries/62a69d6cb35db4f20e37703a/cases')
   @pytest.mark.parametrize('req,resp,title', SID_0x19_reportNumberOfDTCByStatusMask_noFault, ids=ids)
   def test_reportNumberOfDTCByStatusMask_No_Fault_extended_Phy(self, action,  Driver, req, resp, title):
      iStep = 1
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False, 'UDS', 'ClearFault')
      with allure.step(f'Step{iStep}: Judge fault number of times'):
         with assume: assert uds_resp[5] <= 3 
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19,0x02,0x09], [0x59,0x02,0x09], 0, iStep, False, 'UDS', 'noClearFault')
      iStep = Driver['CAN'].delInitialFailure(iStep,uds_resp)

   @allure.severity('normal')
   @allure.description('Test reportNumberOfDTCByStatusMask of 0x19 when faults occur in default session with physical addressing')
   @allure.testcase('Test cases address:https://chengtech.pingcode.com/testhub/libraries/62a69d6cb35db4f20e37703a/cases')
   def test_reportNumberOfDTCByStatusMask_Have_Fault_Default_Phy(self, action,  Driver):
      time.sleep(1)
      iStep = 1
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00], 1, iStep, False, 'UDS', 'ClearFault')
      with allure.step(f'Step{iStep}: Judge fault number of times'):
         with assume: assert uds_resp[5] <= 3 
         faultCount = uds_resp[5]
      self.TestFault(Driver, iStep,faultCount)

   @allure.severity('normal')
   @allure.description('Test reportNumberOfDTCByStatusMask of 0x19 when faults occur in extended session with physical addressing')
   @allure.testcase('Test cases address:https://chengtech.pingcode.com/testhub/libraries/62a69d6cb35db4f20e37703a/cases')
   def test_reportNumberOfDTCByStatusMask_Have_Fault_Extended_Phy(self, action,  Driver):
      iStep = 1
      time.sleep(1)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00], 3, iStep, False, 'UDS', 'ClearFault')
      with allure.step(f'Step{iStep}: Judge fault number of times'):
         with assume: assert uds_resp[5] <= 3 
         faultCount = uds_resp[5]
      self.TestFault(Driver, iStep,faultCount)


   







   def TestFault(self, Driver, iStep, faultCount=3):
      # 设置电压为17V，并等待1.5s 制造 Overvoltage 故障，读取当前故障数量
      iStep = Driver['CAN'].SetVolt(Driver, 17, 1.5, iStep)
      faultCount += 1 
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # 设置电压为12V，并等待1.5s 恢复 Overvoltage 故障，读取当前故障数量
      iStep = Driver['CAN'].SetVolt(Driver, 12, 1.5, iStep)
      faultCount -= 1
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # 设置电压为8.5V，并等待1.5s 制造 Undervoltage 故障，读取当前故障数量
      iStep = Driver['CAN'].SetVolt(Driver, 8.5, 1.5, iStep)
      faultCount += 1 
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # 设置电压为12V，并等待1.5s 恢复 Undervoltage 故障，读取当前故障数量
      iStep = Driver['CAN'].SetVolt(Driver, 12, 1.5, iStep)
      faultCount -= 1 
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')


      '''制造 timeout 错误，故障数量需要累加'''
      # 制造 DTC_Left_BCM_TIMEOUT 故障，读取当前故障数量
      iStep = Driver['CAN'].DTC_Left_BCM_TIMEOUT(iStep, True)
      faultCount += 1 
      time.sleep(0.1)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # 制造 DTC_Media_TIMEOUT 故障，读取当前故障数量
      iStep = Driver['CAN'].DTC_Media_TIMEOUT(iStep, True)
      faultCount += 1 
      time.sleep(0.1)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # 制造 DTC_VCU_TIMEOUT 故障，读取当前故障数量
      iStep = Driver['CAN'].DTC_VCU_TIMEOUT(iStep, True)
      faultCount += 1 
      time.sleep(0.1)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # 制造 DTC_IPB_TIMEOUT_IPB121 故障，读取当前故障数量
      iStep = Driver['CAN'].DTC_IPB_TIMEOUT_IPB121(iStep, True)
      faultCount += 1 
      time.sleep(0.1)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # 制造 DTC_EPS_TIMEOUT 故障，读取当前故障数量
      iStep = Driver['CAN'].DTC_EPS_TIMEOUT(iStep, True)
      faultCount += 1 
      time.sleep(0.1)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      '''恢复 timeout 错误，故障数量需要递减'''
      # 恢复 DTC_Left_BCM_TIMEOUT 故障，读取当前故障数量
      iStep = Driver['CAN'].DTC_Left_BCM_TIMEOUT(iStep, False)
      faultCount -= 1 
      time.sleep(0.1)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # 恢复 DTC_Media_TIMEOUT 故障，读取当前故障数量
      iStep = Driver['CAN'].DTC_Media_TIMEOUT(iStep, False)
      faultCount -= 1 
      time.sleep(0.1)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # 恢复 DTC_VCU_TIMEOUT 故障，读取当前故障数量
      iStep = Driver['CAN'].DTC_VCU_TIMEOUT(iStep, False)
      faultCount -= 1 
      time.sleep(0.1)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # 恢复 DTC_IPB_TIMEOUT_IPB121 故障，读取当前故障数量
      iStep = Driver['CAN'].DTC_IPB_TIMEOUT_IPB121(iStep, False)
      faultCount -= 1 
      time.sleep(0.1)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # 恢复 DTC_EPS_TIMEOUT 故障，读取当前故障数量
      iStep = Driver['CAN'].DTC_EPS_TIMEOUT(iStep, False)
      faultCount -= 1 
      time.sleep(0.1)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      '''制造 checksum 错误，故障数量需要累加'''
      # 制造 DTC_VCU_CRC 故障，并等待（周期20，次数3）
      Driver['CAN'].set_0x342_checksum_error(True)
      faultCount += 1
      time.sleep(20*4/1000 + 0.5)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # # 制造 DTC_IPB_CRC 故障，并等待（周期20，次数3）
      # Driver['CAN'].set_0x220_checksum_error(True)
      # time.sleep(3)
      # iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, 0x05], 0, iStep, False, 'UDS', 'noClearFault')

      # 制造 DTC_EPS_CRC 故障，并等待（周期10，次数3）
      Driver['CAN'].set_0x422_checksum_error(True)
      faultCount += 1 
      time.sleep(10*4/1000 + 0.5)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      '''恢复 checksum 错误，故障数量需要递减'''
      # 恢复 DTC_VCU_CRC 故障，并等待（周期20，次数3）
      Driver['CAN'].set_0x342_checksum_error(False)
      faultCount -= 1 
      time.sleep(20*4/1000 + 0.5)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # # 恢复 DTC_IPB_CRC 故障，并等待（周期20，次数3）
      # Driver['CAN'].set_0x220_checksum_error(False)
      # time.sleep(20*4/1000)
      # iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, 0x04], 0, iStep, False, 'UDS', 'noClearFault')

      # 恢复 DTC_EPS_CRC 故障，并等待（周期10，次数3）
      Driver['CAN'].set_0x422_checksum_error(False)
      faultCount -= 1 
      time.sleep(10*4/1000 + 0.8)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      '''制造 Rolling_counter 错误，故障数量需要累加'''

      # 制造 DTC_VCU_ALC 故障，并等待（周期20，次数3）
      Driver['CAN'].set_0x342_rolling_counter_error(True)
      faultCount += 1 
      time.sleep(20*4/1000 + 0.8)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # 制造 DTC_EPS_ALC 故障，并等待（周期20，次数3）
      Driver['CAN'].set_0x11F_rolling_counter_error(True)
      faultCount += 1 
      time.sleep(10*4/1000 + 0.5)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      '''恢复 Rolling_counter 错误，故障数量需要递减'''
  
      # 恢复 DTC_VCU_ALC 故障，并等待（周期20，次数3）
      Driver['CAN'].set_0x342_rolling_counter_error(False)
      faultCount -= 1 
      time.sleep(20*4/1000 + 0.5)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # 恢复 DTC_EPS_ALC 故障，并等待（周期20，次数3）
      Driver['CAN'].set_0x11F_rolling_counter_error(False)
      faultCount -= 1 
      time.sleep(10*4/1000 + 0.5)
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # # 制造 VCAN canH connect canL
      # iStep = Driver['CAN'].V_ConnectCanH_CanL(True, iStep)
      # iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # # 恢复 VCAN canH connect canL
      # iStep = Driver['CAN'].V_ConnectCanH_CanL(False, iStep)
      # iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # # 制造 VCAN canH connect GND
      # iStep = Driver['CAN'].V_ConnectCanH_GND(True, iStep)
      # iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # # 恢复 VCAN canH connect GND
      # iStep = Driver['CAN'].V_ConnectCanH_GND(False, iStep)
      # iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # # 制造 VCAN canL connect VCC
      # iStep = Driver['CAN'].V_ConnectCanL_Vcc(True, iStep)
      # iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      # # 恢复 VCAN canL connect VCC
      # iStep = Driver['CAN'].V_ConnectCanL_Vcc(False, iStep)
      # iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x01, 0x01], [0x59, 0x01, 0x09, 0x00, 0x00, faultCount], 0, iStep, False, 'UDS', 'noClearFault')

      '''清除所有故障'''
      iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x14, 0xFF, 0xFF, 0xFF], [0x54], 0, iStep, False, 'UDS', 'noClearFault')
